package com.ccnf.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.ccnf.core.utils.ResultUtil;
import com.ccnf.core.utils.SystemClock;
import com.ccnf.model.entity.*;
import com.ccnf.model.mapper.*;
import com.ccnf.model.pojo.InvitationRewardVo;
import com.ccnf.model.pojo.PrizeVo;
import com.ccnf.service.RewardService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class RewardServiceImpl implements RewardService {
    @Autowired
    private InvitationRewardMapper invitationRewardMapper;
    @Autowired
    private InvitationRecordMapper invitationRecordMapper;
    @Autowired
    private InvitationAccountMapper invitationAccountMapper;
    @Autowired
    private AccountRecordMapper accountRecordMapper;
    @Autowired
    private InvitationReportMapper invitationReportMapper;
    @Autowired
    private RewardPrizeMapper rewardPrizeMapper;

    @Override
    @Transactional
    public void handleRewardRecord(long zeroTime) {
        List<InvitationRewardVo> invitationRewardVos = invitationRewardMapper.selectEveryDayRewardInvitation(zeroTime);
        invitationRewardVos.forEach(invitationRewardVo -> {
            int rewardType = invitationRewardVo.getRewardType();// 赏金类型
            int recordType = invitationRewardVo.getRecordType();// 统计数据类型0：浏览，1：登记，2：入场
            int totalNum = invitationRewardVo.getTotalNum();// 统计人数值
            BigDecimal reward = new BigDecimal(0);// 用于保存获取到的赏金
            Long invitationId = invitationRewardVo.getInvitationId();// 用户邀请函ID
            Long referenceId = invitationRewardVo.getReferenceId();// 用户引用的邀请函ID
            Long userId = invitationRewardVo.getUserId();// 赚取赏金的用户ID
            if (recordType == 2) {
                // 实物奖励

            } else {
                // 需要使用账户信息
                if (rewardType == 0) {
                    // 取赏金随机值的上、下限值，做随机值
                    double max = invitationRewardVo.getUpReward().doubleValue();
                    double min = invitationRewardVo.getDownReward().doubleValue();
                    double randomReward = Math.round((Math.random() * (max - min) + min) * 100) / 100.0;// 获取的随机赏金值
                    int num = Math.floorDiv(totalNum, invitationRewardVo.getRecordNum());
                    reward = new BigDecimal(randomReward * num);// 总共获得的赏金值
                } else if (rewardType == 1) {
                    // 排名奖励
                    if (invitationRecordMapper.selectInvitationCurrentUserRank(invitationId, referenceId, recordType, 1, zeroTime) == 1) {
                        // 排名是第一名
                        reward = invitationRewardVo.getRankReward();// 排名奖励金额
                    }
                }
                if (reward.doubleValue() != 0) {
                    // 录入用户账户表
                    Long accountId = handleInvitationAccount(invitationId, referenceId, userId, reward);
                    // 录入用户账户记录
                    AccountRecord accountRecord = new AccountRecord();
                    accountRecord.setAccountId(accountId);
                    accountRecord.setRewardId(invitationRewardVo.getRewardId());
                    accountRecord.setIncome(reward);
                    String desc = handleRecordType(recordType);// 得到统计类型对应的文字描述
                    if (rewardType == 0) {
                        accountRecord.setIncomeDesc("用户的" + desc + "数据到达" + totalNum + "人，赚取" + reward.floatValue() + "赏金");
                    } else {
                        accountRecord.setIncomeDesc("用户的" + desc + "数据到达" + totalNum + "人，排名第一名，赚取" + reward.floatValue() + "赏金");
                    }
                    accountRecordMapper.insert(accountRecord);
                }
            }
        });
        handleRealPrize(zeroTime + 86400);
    }

    /**
     * 处理实物奖励
     * @param second 当天零点时间
     */
    private void handleRealPrize(long second) {
        List<InvitationReward> invitationRewards = invitationRewardMapper.selectRealReward(new Date(second * 1000));
        invitationRewards.forEach(invitationReward -> {
            Long referenceId = invitationReward.getInvitationId();
            List<RewardPrize> rewardPrizes = rewardPrizeMapper.selectPrizeByInvitationId(referenceId);
            Page page = new Page(1, rewardPrizes.size());
            List<Map<String, Object>> maps = invitationReportMapper.selectUserRank(referenceId, second,
                    invitationReward.getRecordType(), invitationReward.getRecordNum(), page);
            if (maps != null && maps.size() > 0) {
                for (int i = 0; i < maps.size(); i++) {
                    RewardPrize rewardPrize = rewardPrizes.get(i);
                    rewardPrize.setUserId((Long) maps.get(i).get("user_id"));
                    rewardPrize.setPrizeStatus(1);
                    rewardPrize.setCreateTime(SystemClock.second());
                    rewardPrizeMapper.updateById(rewardPrize);
                }
            }
        });
    }

    @Override
    public List<InvitationReward> findRewardByInvitationId(Long invitationId) {
        InvitationReward invitationReward = new InvitationReward();
        invitationReward.setInvitationId(invitationId);
        invitationReward.setIsDeleted(0);
        return invitationRewardMapper.selectList(new EntityWrapper<>(invitationReward));
    }

    @Override
    public List<PrizeVo> findWinnerUserList(Long invitationId) {
        return rewardPrizeMapper.selectWinnerUser(invitationId);
    }

    @Override
    public RewardPrize findUserPrize(Long invitationId, Long userId) {
        return rewardPrizeMapper.selectUserPrize(invitationId, userId);
    }

    @Override
    public RewardPrize findPrizeByPrizeId(Long prizeId) {
        return rewardPrizeMapper.selectById(prizeId);
    }

    @Override
    public void modifyPrizeByPrizeId(RewardPrize rewardPrize) {
        Integer prizeStatus = rewardPrize.getPrizeStatus();
        if (prizeStatus != null && prizeStatus == 2) {
            rewardPrize.setTakeTime(SystemClock.second());
        }
        ResultUtil.validateSQL(rewardPrizeMapper.updateById(rewardPrize), "修改奖品失败");
    }

    /**
     * 处理统计数据类型对应的文字描述
     * @param recordType 统计类型
     * @return 对应的文字描述
     */
    private String handleRecordType(int recordType) {
        String str = "";
        switch (recordType) {
            case 0:
                str = "浏览";
                break;
            case 1:
                str = "登记";
                break;
            case 2:
                str = "入场";
                break;
        }
        return str;
    }

    /**
     * 处理用户邀请函账户信息
     * @param invitationId 邀请函ID
     * @param referenceId 引用的邀请函ID
     * @param userId 用户ID
     * @param reward 赏金金额
     * @return 账户ID
     */
    private Long handleInvitationAccount(Long invitationId, Long referenceId, Long userId, BigDecimal reward) {
        Long accountId;// 用于保存账户ID
        InvitationAccount selectInvitationAccount = new InvitationAccount();
        selectInvitationAccount.setReferenceId(referenceId);
        selectInvitationAccount.setUserId(userId);
        InvitationAccount invitationAccount = invitationAccountMapper.selectOne(selectInvitationAccount);// 查询用户邀请函账户信息
        if (invitationAccount == null) {
            // 不存在用户邀请函的账户信息
            selectInvitationAccount.setAccountMoney(reward);
            selectInvitationAccount.setUserId(userId);
            selectInvitationAccount.setInvitationId(invitationId);
            invitationAccountMapper.insert(selectInvitationAccount);
            accountId = selectInvitationAccount.getAccountId();
        } else {
            // 存在用户邀请函的账户信息
            accountId = invitationAccount.getAccountId();
            invitationAccountMapper.addAccountMoney(accountId, reward);
        }
        return accountId;
    }
}